YAHOO.namespace('springmole');

(function () {
	
	
	YAHOO.springmole.HibernatePanel = function (el, userConfig) {
		YAHOO.springmole.HibernatePanel.superclass.constructor.call(this, el, userConfig);
	};
	
	
	
	var ROOT_TABVIEW_ID = 'root_tabview_id',
		PROPERTY_TABVIEW_ID = 'property_tabview_id',
		STATISTIC_TABVIEW_ID = 'statistic_tabview_id',
	
		PROPERTY_TABVIEW_INDEX = 0,
		STATISTIC_TABVIEW_INDEX = 1,
	
		SUMMARY_CONTENT_ID = 'summary_content_id',
		
		ENTITY_TABLE_ID = 'entity_table_id',
		COLLECTION_TABLE_ID = 'collection_table_id',
		QUERY_TABLE_ID = 'query_table_id',
		SECONDLEVEL_TABLE_ID = 'secondlevel_table_id',
	
		REFRESH_BUTTON_ID = 'refresh_button_id',
	
		HIBERNATE_DATASOURCE_URL = 'hibernate.spy?',
	
		DEFAULT_CONFIG = {
			'ACTIVE_TAB_INDEX': { 
				key: 'activetabindex', 
				value: 0
			}
		},
	
		rootTabView,
		entityTable, collectionTable, queryTable, secondLevelCacheTable,
	
		showTableFunctionArray;
	
	
	/**
	 * 
	 * @param {Object} tableId
	 * @param {Object} columnDefinition
	 * @param {Object} fieldArray
	 */
	function createTable(tableId, columnDefinition, fieldArray, panelHeight, data) {
		var dataSource = new YAHOO.util.DataSource(data);
		dataSource.responseType = YAHOO.util.DataSource.TYPE_XML;
		dataSource.useXPath = true;
		dataSource.responseSchema = {
			resultNode: 'Data',
			fields: fieldArray
		};
	
		return new YAHOO.widget.ScrollingDataTable(tableId, columnDefinition, dataSource, {
			dynamicData: false, 
			width: '100%',
			height: (panelHeight - 175) + 'px',
			draggableColumns: true
		});
	}
	
	
	/**
	 * 
	 * @param {Object} url
	 * @param {Object} successCallback
	 */
	function executeGetRequest(url, successCallback, table) {
		
		var callback = {
			success : function (response) {
				var datatable, sortedBy;
				
				// TODO: fix argument limitation
				if (response.argument[0]) {
					datatable = response.argument[0];
					sortedBy = datatable.get('sortedBy');				
				}
							
				successCallback(response);
				
				if (sortedBy) {
					datatable.sortColumn(datatable.getColumn(sortedBy.key), sortedBy.dir);				
				}
	
			},
			error : function (response) {
				alert('error');
			},
			failure : function (response) {
				alert('failure');
			},
			argument: [table]
		};
		YAHOO.util.Connect.asyncRequest('GET', url, callback);
	}
	
	
	function showSystemTable() {
		
	}
	
	function showEnvironmentTable() {
		
	}
	
	
	function showSummaryContent(panelHeight) {
		var summaryContainer = YAHOO.util.Dom.get(SUMMARY_CONTENT_ID);
		
		executeGetRequest('hibernate.spy?summary=content', function (response) {
			summaryContainer.innerHTML = response.responseText;
		});	
		
		YAHOO.util.Dom.setStyle(summaryContainer, 'height', (panelHeight - 150) + 'px');
	}
	
	
	/**
	 * 
	 * @param {Object} tableHeight
	 */
	function showEntityTable(tableHeight) {
		var 
		url,
		columnDefinition,
		fieldArray;
		
		url = HIBERNATE_DATASOURCE_URL + 'tableid=' + ENTITY_TABLE_ID;
		
		if (entityTable) {
			executeGetRequest(url, function (response) {
				// Replace local data
				entityTable.requery(response.responseXML);
			}, entityTable);
		} else {
			columnDefinition = [
				{key: 'category', sortable: true, resizeable: true},
				{key: 'insert', sortable: true, resizeable: true},
				{key: 'delete', sortable: true, resizeable: true},
				{key: 'update', sortable: true, resizeable: true},
				{key: 'load', sortable: true, resizeable: true},
				{key: 'fetch', sortable: true, resizeable: true},
				{key: 'optimisticFailure', sortable: true, resizeable: true}
			];
		    
			fieldArray = [
				{key: 'category', locator: '@category', parser: 'string'},
				{key: 'insert', locator: '@insert', parser: 'number'},
				{key: 'delete', locator: '@delete', parser: 'number'},
				{key: 'update', locator: '@update', parser: 'number'},
				{key: 'load', locator: '@load', parser: 'number'},
				{key: 'fetch', locator: '@fetch', parser: 'number'},
				{key: 'optimisticFailure', locator: '@optimisticFailure', parser: 'number'}
			];
		
			executeGetRequest(url, function (response) {
				var data = response.responseXML;
				entityTable = createTable(ENTITY_TABLE_ID, columnDefinition, fieldArray, tableHeight, data);
			});
		}
	}
	
	
	/**
	 * 
	 * @param {Object} tableHeight
	 */
	function showCollectionTable(tableHeight) {
		var 
		url,
		columnDefinition,
		fieldArray;
		
		
		url = HIBERNATE_DATASOURCE_URL + 'tableid=' + COLLECTION_TABLE_ID;
		
		if (collectionTable) {
			executeGetRequest(url, function (response) {
				collectionTable.requery(response.responseXML);
			}, collectionTable);		
		} else {
			columnDefinition = [
				{key: 'category', sortable: true, resizeable: true},
				{key: 'load', sortable: true, resizeable: true},
				{key: 'fetch', sortable: true, resizeable: true},
				{key: 'update', sortable: true, resizeable: true},
				{key: 'remove', sortable: true, resizeable: true},
				{key: 'recreate', sortable: true, resizeable: true}
			];
	    
			fieldArray = [
				{key: 'category', locator: '@category', parser: 'string'},
				{key: 'load', locator: '@load', parser: 'number'},
				{key: 'fetch', locator: '@fetch', parser: 'number'},
				{key: 'update', locator: '@update', parser: 'number'},
				{key: 'remove', locator: '@remove', parser: 'number'},
				{key: 'recreate', locator: '@recreate', parser: 'number'}
			];
		    
			executeGetRequest(url, function (response) {
				var data = response.responseXML;
				collectionTable = createTable(COLLECTION_TABLE_ID, columnDefinition, fieldArray, tableHeight, data);
			});			
		}
	}
	
	
	/**
	 * 
	 * @param {Object} tableHeight
	 */
	function showQueryTable(tableHeight) {
		var 
		url,
		columnDefinition,
		fieldArray;
		
		url = HIBERNATE_DATASOURCE_URL + 'tableid=' + QUERY_TABLE_ID;
		
		if (queryTable) {
			executeGetRequest(url, function (response) {
				queryTable.requery(response.responseXML);
			}, queryTable);
		} else {
			columnDefinition = [
				{key: 'category', sortable: true, resizeable: true},
				{key: 'cacheHitCount', sortable: true, resizeable: true},
				{key: 'cacheMissCount', sortable: true, resizeable: true},
				{key: 'cachePutCount', sortable: true, resizeable: true},
				{key: 'executionAvgTime', sortable: true, resizeable: true},
				{key: 'executionCount', sortable: true, resizeable: true},
				{key: 'countOnDisk', sortable: true, resizeable: true},
				{key: 'executionMinTime', sortable: true, resizeable: true},
				{key: 'executionRowCount', sortable: true, resizeable: true}
			];
		    
			fieldArray = [
				{key: 'category', locator: '@category', parser: 'string'},
				{key: 'cacheHitCount', locator: '@cacheHitCount', parser: 'number'},
				{key: 'cacheMissCount', locator: '@cacheMissCount', parser: 'number'},
				{key: 'cachePutCount', locator: '@cachePutCount', parser: 'number'},
				{key: 'executionAvgTime', locator: '@executionAvgTime', parser: 'number'},
				{key: 'executionCount', locator: '@executionCount', parser: 'number'},
				{key: 'executionMaxTime', locator: '@executionMaxTime', parser: 'number'},
				{key: 'executionMinTime', locator: '@executionMinTime', parser: 'number'},
				{key: 'executionRowCount', locator: '@executionRowCount', parser: 'number'}
			];
		    
			executeGetRequest(url, function (response) {
				var data = response.responseXML;
				queryTable = createTable(QUERY_TABLE_ID, columnDefinition, fieldArray, tableHeight, data);
			});		
		}	
	}
	
	
	function showSecondLevelCacheTable(tableHeight) {
		var
		url,
		columnDefinition,
		fieldArray;
		
		url = HIBERNATE_DATASOURCE_URL + 'tableid=' + SECONDLEVEL_TABLE_ID;
		
		if (secondLevelCacheTable) {
			executeGetRequest(url, function (response) {
				secondLevelCacheTable.requery(response.responseXML);
			}, secondLevelCacheTable);
		} else {
			columnDefinition = [
				{key: 'category', sortable: true, resizeable: true},
				{key: 'put', sortable: true, resizeable: true},
				{key: 'hit', sortable: true, resizeable: true},
				{key: 'miss', sortable: true, resizeable: true},
				{key: 'sizeInMemory', sortable: true, resizeable: true},
				{key: 'countInMemory', sortable: true, resizeable: true},
				{key: 'countOnDisk', sortable: true, resizeable: true}
			];
		    
			fieldArray = [
				{key: 'category', locator: '@category', parser: 'string'},
				{key: 'put', locator: '@put', parser: 'number'},
				{key: 'hit', locator: '@hit', parser: 'number'},
				{key: 'miss', locator: '@miss', parser: 'number'},
				{key: 'sizeInMemory', locator: '@sizeInMemory', parser: 'number'},
				{key: 'countInMemory', locator: '@countInMemory', parser: 'number'},
				{key: 'countOnDisk', locator: '@countOnDisk', parser: 'number'}
			];
		    
			executeGetRequest(url, function (response) {
				var data = response.responseXML;
				secondLevelCacheTable = createTable(SECONDLEVEL_TABLE_ID, columnDefinition, fieldArray, tableHeight, data);
			});		
		}
	}
	
	showTableFunctionArray = [
		[showSystemTable, showEnvironmentTable], 
	    [showSummaryContent, showEntityTable, showCollectionTable, showQueryTable, showSecondLevelCacheTable]
	];
	
	
	// TODO: rewrite
	function resizeContent(args) {
		var tableHeight = (args.height - 175) + 'px';
		
		if (entityTable) {
			entityTable.set('height', tableHeight);	
		}
		if (collectionTable) {
			collectionTable.set('height', tableHeight);
		}
		if (queryTable) {
			queryTable.set('height', tableHeight);
		}
		if (secondLevelCacheTable) {
			secondLevelCacheTable.set('height', tableHeight);
		}
		
		YAHOO.util.Dom.setStyle(SUMMARY_CONTENT_ID, 'height', (args.height - 150) + 'px');
	}
	
	
	function configActiveTabIndex(type, args, obj) {
		rootTabView.selectTab(args[0]);
	}
	
	
	YAHOO.lang.extend(YAHOO.springmole.HibernatePanel, YAHOO.springmole.SpringMolePanel, {
	  
		initDefaultConfig: function () {
			YAHOO.springmole.HibernatePanel.superclass.initDefaultConfig.call(this);
			
			this.cfg.addProperty(DEFAULT_CONFIG.ACTIVE_TAB_INDEX.key, {
				handler: configActiveTabIndex,
				value: DEFAULT_CONFIG.ACTIVE_TAB_INDEX.value
			});
			
		},
		
		render: function (parentNode) {
			var activeTabIndex, 
				propertyTabView, 
				statisticTabView, 
				refreshButton;

			this.setHeader("Hibernate");
			this.setBody('<div id="' + ROOT_TABVIEW_ID + '"></div>');
			this.setFooter('<input id="' + REFRESH_BUTTON_ID + '"/>');

			YAHOO.springmole.HibernatePanel.superclass.render.call(this, parentNode);

			activeTabIndex = this.cfg.getProperty(DEFAULT_CONFIG.ACTIVE_TAB_INDEX.key);

			rootTabView = new YAHOO.widget.TabView(ROOT_TABVIEW_ID);

			rootTabView.addTab(new YAHOO.widget.Tab({
				label : 'Properties',
				content : '<div id="' + PROPERTY_TABVIEW_ID + '"></div>',
				active : activeTabIndex === 0
			}));
			rootTabView.addTab(new YAHOO.widget.Tab({
				label : 'Statitics',
				content : '<div id="' + STATISTIC_TABVIEW_ID + '"></div>',
				active : activeTabIndex === 1
			}));

			propertyTabView = new YAHOO.widget.TabView(PROPERTY_TABVIEW_ID);
			propertyTabView.addTab(new YAHOO.widget.Tab({
				label : 'System',
				content : 'sys',
				active : true
			}));
			propertyTabView.addTab(new YAHOO.widget.Tab({
				label : 'Environment',
				content : 'env'
			}));

			statisticTabView = new YAHOO.widget.TabView(STATISTIC_TABVIEW_ID);
			statisticTabView.addTab(new YAHOO.widget.Tab({
				label : 'Summary',
				content : '<div id="' + SUMMARY_CONTENT_ID + '"></div>',
				active : true
			}));
			statisticTabView.addTab(new YAHOO.widget.Tab({
				label : 'Entities',
				content : '<div id="' + ENTITY_TABLE_ID + '"></div>'
			}));
			statisticTabView.addTab(new YAHOO.widget.Tab({
				label : 'Collections',
				content : '<div id="' + COLLECTION_TABLE_ID + '"></div>'
			}));
			statisticTabView.addTab(new YAHOO.widget.Tab({
				label : 'Querys',
				content : '<div id="' + QUERY_TABLE_ID + '"></div>'
			}));
			statisticTabView.addTab(new YAHOO.widget.Tab({
				label : 'Second Level cache',
				content : '<div id="' + SECONDLEVEL_TABLE_ID + '"></div>'
			}));
			statisticTabView.on('activeTabChange', function (ev) {
				var panelHeight, tabIndex;

				panelHeight = YAHOO.util.Dom.getRegion(this.element).height;
				tabIndex = statisticTabView.getTabIndex(ev.newValue);
				showTableFunctionArray[1][tabIndex](panelHeight);
			}, this, true);

			refreshButton = new YAHOO.widget.Button(REFRESH_BUTTON_ID, {
				type : 'button',
				label : "Refresh"
			});
			refreshButton.on('click', function () {
				var panelHeight = YAHOO.util.Dom.getRegion(this.element).height;

				if (rootTabView.get('activeIndex') === PROPERTY_TABVIEW_INDEX) {
					showTableFunctionArray[PROPERTY_TABVIEW_INDEX][propertyTabView.get('activeIndex')](panelHeight);
				} else {
					showTableFunctionArray[STATISTIC_TABVIEW_INDEX][statisticTabView.get('activeIndex')](panelHeight);
				}
			}, this, true);

			this._panelResize.on('resize', resizeContent);
			
			

			if (activeTabIndex === 1) {
				showSummaryContent(400);
			}
		} // render
	  
	}); // extend Panel
	


}());